#include "linkfabric/SDK.hpp"

using namespace linkfabric;
/*
bool SDK::init(const std::string& devicePath) {
    return fabric_.init(devicePath);
}
*/
int SDK::openChannel() {
    return fabric_.openChannel(ChannelPermission::READWRITE);
}

void SDK::closeChannel(int channelId) {
    fabric_.freeChannel(channelId);
}

bool SDK::sendMessage(int channelId, uint8_t msgType, const std::map<uint8_t, std::string>& fields, const std::string& key) {
    Message msg;
    msg.header.version = 1;
    msg.header.msg_type = msgType;
    msg.header.flags = key.empty() ? 0 : 1;
    msg.header.channel_id = channelId;

    for (const auto& [tag, val] : fields) {
        std::vector<uint8_t> raw(val.begin(), val.end());
        if (!key.empty()) raw = Crypto::encrypt(raw, key);
        msg.body.emplace_back(tag, raw);
    }

    auto encoded = msg.encode();
    msg.header.total_length = encoded.size();
    return fabric_.send(channelId, msg.body);
}

void SDK::onMessage(int channelId, std::function<void(uint8_t, std::map<uint8_t, std::string>)> callback) {
    handlers_[channelId] = callback;
    fabric_.onReceive(channelId, [this, channelId](const std::vector<TLV>& tlvs) {
        std::map<uint8_t, std::string> result;
        for (const auto& tlv : tlvs) {
            std::string val(tlv.value.begin(), tlv.value.end());
            result[tlv.tag] = val;
        }
        handlers_[channelId](0x01, result); // msgType stub
    });
}

void SDK::run() {
    fabric_.run();
}
